/*
 * Copyright (C) 2000-2008 Jens Nixdorf and various contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies of the Software, its documentation and marketing & publicity
 * materials, and acknowledgment shall be given in the documentation, materials
 * and software packages that this Software was used.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package org.mopore.jat.core.externalplugins;

import java.awt.Font;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import net.iharder.dnd.FileDrop;

import org.mopore.jat.gui.Theme;
import org.mopore.jat.util.ImageService;

public class ExternalPluginManagerDialog  extends JFrame{

	
	private static final String NO_SELECTION = "<no selection>";
	private ExternalPluginManager manager;
	private JLabel versionValueLabel;
	private JList list;

	public ExternalPluginManagerDialog( ExternalPluginManager manager ){

		final Theme currentTheme = manager.getCurrentTheme();
		this.manager = manager;
		BufferedImage image = ImageService.load( currentTheme.getPath() );
		setIconImage(image);
		setSize(400, 230);
		
		new  FileDrop( this, new FileDrop.Listener()
	      {   public void  filesDropped( java.io.File[] files ) {   
	    	  if ( files.length != 1 ) {
	    		  JOptionPane.showMessageDialog( 
	    				  ExternalPluginManagerDialog.this, 
	    				  "Please select only one file to install.", 
	    				  "Error adding plugin", 
	    				  JOptionPane.ERROR_MESSAGE
	    		  );
	    		  return;
	    	  }
	    	  File file = files[0];
	    	  boolean accept = new JatZipFileFilter().accept( file );
	    	  if ( ! accept ) {
	    		  JOptionPane.showMessageDialog( 
	    				  ExternalPluginManagerDialog.this, 
	    				  "Please select a jat plugin file (*.jat.zip).", 
	    				  "Error adding plugin", 
	    				  JOptionPane.ERROR_MESSAGE
	    		  );
	    		  return;
	    	  }
	    		  
	    	  ExternalPluginManagerDialog.this.manager.addExternalPlugin( file );
	      }
	    }); 
		
		
		Toolkit t = this.getToolkit();
		this.setLocation(
				(int) ((t.getScreenSize().getWidth() - this.getWidth()) / 2),
				(int) ((t.getScreenSize().getHeight() - this.getHeight()) / 2));
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		setTitle("mopore-jat plugin manager");

		JPanel panel = createPluginManagerPanelContent();
		setContentPane(panel);
		setResizable(false);
	}
	
	private JPanel createPluginManagerPanelContent() {

		JPanel panel = new JPanel();
		panel.setLayout( null );
		
		String[] plugingNames = manager.listExternalPluginsNames();
		DefaultListModel model = new DefaultListModel();
		
		for (String pluginName : plugingNames) {
			model.addElement( pluginName );
		}
		
		this.list = new JList( model );
		attachSelectionListener( list );
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.getViewport().setView(list);
		scrollPane.setBounds( 10, 10, 260, 165 );
		
		panel.add( scrollPane );
		
		JButton addButton = new JButton( "add..." );
		addButton.addActionListener(
				new AddExternalPluginAction( manager, this )
		);
		addButton.setBounds( 300, 10, 80, 30 );
		panel.add( addButton );

		JButton removeButton = new JButton( "remove" );
		removeButton.setBounds( 300, 50, 80, 30 );
		attachRemoveAction( removeButton );
		panel.add( removeButton );
		
		JLabel versionTextLabel = new JLabel( "plugin version:" );
		versionTextLabel.setBounds( 302, 88, 80, 30 );
		panel.add( versionTextLabel );
		
		this.versionValueLabel = new JLabel( NO_SELECTION );
		versionValueLabel.setBounds( 302, 102, 80, 30 );
		panel.add( versionValueLabel );
		
		JLabel pluginInfoLabel = new JLabel( "Note: Alternatively you can use 'drag & drop' to add a new plugin." );
		pluginInfoLabel.setBounds( 11, 174, 320, 30 );
		Font italicFont = 
			pluginInfoLabel.getFont().deriveFont( Font.ITALIC );
		pluginInfoLabel.setFont( italicFont );
		panel.add( pluginInfoLabel );
		
		return panel;
	}

	
	public void removePluginEntry( String pluginName ) {
		
		DefaultListModel model = (DefaultListModel) list.getModel();
		model.removeElement( pluginName );
		invalidate();
		validate();
		list.clearSelection();
	}
	
	
	public void addPluginEntry( String pluginName ) {
		
		DefaultListModel model = (DefaultListModel) list.getModel();
		model.addElement( pluginName );
		invalidate();
		validate();
		list.setSelectedValue( pluginName, true );
	}
	
	
	
	private void attachRemoveAction(JButton removeButton) {
		
		RemoveExternalPluginAction action = 
			new RemoveExternalPluginAction( manager, this );
		removeButton.addActionListener( action );
	}

	private void attachSelectionListener(JList list) {
		list.addListSelectionListener( new ListSelectionListener() {

			@Override
			public void valueChanged(ListSelectionEvent e) {
				JList list = (JList) e.getSource();
				String pluginName = (String) list.getSelectedValue();
				String text;
				if ( pluginName == null ) {
					text = NO_SELECTION;
				}
				else {
					text = 
					ExternalPluginManagerDialog.this.manager.
						getPluginVersionAsText( pluginName );
				}
				JLabel label = 
					ExternalPluginManagerDialog.this.versionValueLabel;
				label.setText( text );
			}}
		);
		
	}

	public String getSelectedPluginName() {
		
		boolean nothingSelected = list.isSelectionEmpty();
		if ( nothingSelected ) {
			return null;
		}
		
		String pluginName = (String) list.getSelectedValue();
		return pluginName;
	}

	public static void main(String[] args) throws Exception {
		
		UIManager.setLookAndFeel(
				UIManager.getSystemLookAndFeelClassName());
		
		ExternalPluginManager manager = new ExternalPluginManager( null ) {
			@Override
			public Theme getCurrentTheme() {
				return Theme.OCEAN;
			}
			
			/**
			 * This method has been overridden.
			 * @return
			 * @see org.mopore.jat.core.externalplugins.ExternalPluginManager#listExternalPluginsNames()
			 */
			@Override
			public String[] listExternalPluginsNames() {
				return new String[] {
						"org.mopore.jat.Fake"
				};
			}
		};
		JFrame frame = new ExternalPluginManagerDialog( manager );
		frame.setVisible( true );
		
	}


}
